/**
 * 将指定的时间戳、日期对象或日期字符串转换成指定格式的日期和时间
 * @param datetime 时间戳、日期对象或日期字符串
 * @param hasTime 是否需要包含时间部分，默认为 true
 * @param format 日期和时间的格式字符串，默认为 'yyyy-MM-dd HH:mm:ss'
 * @returns 格式化后的日期和时间对象
 */
export default function msToDate(datetime: string | number | Date, hasTime = true, format = 'yyyy-MM-dd HH:mm:ss'): {
  hasTime: string,
  withoutTime: string,
} {
  const date = new Date(datetime);
  const year = date.getFullYear();
  const month = date.getMonth();
  const day = date.getDate();
  const hour = date.getHours();
  const minute = date.getMinutes();
  const second = date.getSeconds();

  // 如果不需要包含时间部分，则只返回日期部分
  if (!hasTime) {
    const withoutTime = format
      .replace(/HH:mm:ss/g, '') // 去掉时间部分
      .replace(/[yYMmd]/g, (match) => {
        switch (match) {
          case 'y':
            return year.toString();
          case 'M':
            return padZero(month + 1);
          case 'd':
            return padZero(day);
          default:
            return match;
        }
      });
    return { hasTime: '', withoutTime };
  }

  // 返回包含日期和时间的完整字符串
  const timestampStr = format
    .replace(/yyyy/g, year.toString())
    .replace(/MM/g, padZero(month + 1))
    .replace(/dd/g, padZero(day))
    .replace(/HH/g, padZero(hour))
    .replace(/mm/g, padZero(minute))
    .replace(/ss/g, padZero(second));
  const withoutTimeStr = timestampStr.replace(/ \d+:\d+:\d+/g, '');

  return { hasTime: timestampStr, withoutTime: withoutTimeStr };
}

/**
 * 在数字前添加前导零，使得长度为指定值，并转成字符串格式
 * @param value 数字值
 * @param length 目标字符串长度
 * @returns 转换后的字符串
 */
function padZero(value: number, length = 2): string {
  return value.toString().padStart(length, '0');
}
